using Elsa.Extensions;
using Elsa.EntityFrameworkCore.Extensions;
using Elsa.EntityFrameworkCore.Modules.Management;
using Elsa.EntityFrameworkCore.Modules.Runtime;
using Microsoft.EntityFrameworkCore;
using DeviceRepairWorkflow.Api.Data;

var builder = WebApplication.CreateBuilder(args);

// Configure URLs
//builder.WebHost.UseUrls("http://localhost:5001");

// Add services to the container.
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
        options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
    });

// Add HttpClient for API calls
builder.Services.AddHttpClient();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo 
    { 
        Title = "Device Repair Workflow API", 
        Version = "v1",
        Description = "API for managing device repair workflows"
    });
});

// Configure application database
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite("Data Source=app.db"));

// Configure CORS
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAngular", policy =>
    {
        policy.WithOrigins("http://localhost:4200")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

// Configure Elsa
builder.Services.AddElsa(elsa =>
{
    // Configure management layer to use EF Core.
    elsa.UseWorkflowManagement(management =>
    {
        management.UseEntityFrameworkCore(ef => ef.UseSqlite("Data Source=elsa.db"));
    });

    // Configure runtime layer to use EF Core.
    elsa.UseWorkflowRuntime(runtime =>
    {
        runtime.UseEntityFrameworkCore(ef => ef.UseSqlite("Data Source=elsa.db"));
    });

    // Default identity features for authentication/authorization.
    elsa.UseIdentity(identity =>
    {
        identity.TokenOptions = options => options.SigningKey = "sufficiently-large-secret-signing-key"; // This key needs to be at least 256 bits long.
        identity.UseAdminUserProvider();
    });

    // Configure ASP.NET authentication/authorization.
    elsa.UseDefaultAuthentication(auth => auth.UseAdminApiKey());

    // Expose Elsa API endpoints.
    elsa.UseWorkflowsApi();

    // Setup a SignalR hub for real-time updates from the server.
    elsa.UseRealTimeWorkflows();

    // Enable HTTP activities.
    elsa.UseHttp();

    // Use timer activities.
    elsa.UseScheduling();

    // Register custom activities from the application, if any.
    elsa.AddActivitiesFrom<Program>();

    // Register custom workflows from the application, if any.
    elsa.AddWorkflowsFrom<Program>();
});

var app = builder.Build();

// Ensure database is created
using (var scope = app.Services.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
    context.Database.EnsureCreated();
}

// Configure the HTTP request pipeline.
app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Device Repair Workflow API v1");
    c.RoutePrefix = "swagger";
});

app.UseCors("AllowAngular");
app.UseAuthentication();
app.UseAuthorization();

// Register Elsa endpoints - this maps the workflow API endpoints
app.UseWorkflows();

// Map application controllers
app.MapControllers();

// Add a simple endpoint to check if Elsa is running
app.MapGet("/elsa/status", () => new { Status = "Elsa Workflows API is running", Version = "3.0.4" });

// Add a simple test endpoint
app.MapGet("/api/test", () => new { Message = "API is working", Timestamp = DateTime.Now });

// Add a simple endpoint to list workflow definitions for testing
app.MapGet("/api/workflow-definitions", async (IServiceProvider serviceProvider) =>
{
    try 
    {
        var workflowDefinitionStore = serviceProvider.GetRequiredService<Elsa.Workflows.Management.Contracts.IWorkflowDefinitionStore>();
        var filter = new Elsa.Workflows.Management.Filters.WorkflowDefinitionFilter();
        var result = await workflowDefinitionStore.FindManyAsync(filter);
        return Results.Ok(new { items = result.ToList(), totalCount = result.Count() });
    }
    catch (Exception ex)
    {
        return Results.Problem($"Error: {ex.Message}");
    }
});

app.Run(); 